using System;
using System.Collections.Generic;
using System.Text;

namespace WillStott.MxAppToolbox
{
    public interface IMxDocument
    {
        /// <summary>
        /// Interface for Document to support a Model-View-Controller architecture. This doesn't make
        /// sense unless you have several views operating on a common document. After adding
        /// the new document class to your project (e.g. MxStdAppDoc) make the following changes:
        /// <list type="number">
        /// <item><description>add interface IMxDocument and implement its methods - see IsDirty()</description></item>
        /// <item><description>define delegate to handle change events and create a public event of this type in your document class i.e. docChange</description></item>
        /// <item><description>add properties for the things you want to store in your Document object</description></item>
        /// <item><description>in each property's setter create a MxDocChangeEventArgs object and pass it to your event i.e. docChange(e)</description></item>
        /// <item><description>Implement the observer in your view class i.e. MainForm</description></item>
        /// </list>
        /// <example>       
        /// <code>
        ///     public delegate void MxStdAppDocEventHandler(MxDocChangeEventArgs e);
        ///
        ///     public class MxStdAppDoc : IMxDocument
        ///     {
        ///         public event MxStdAppDocEventHandler docChange;
        ///         private bool dirtyFlag;
        ///         private string text;
        ///
        ///         public MxStdAppDoc()
        ///         {
        ///             dirtyFlag = false;
        ///         }
        ///
        ///         private void DocChangeEvent(MxDocChangeEventArgs e)
        ///         {
        ///             if (docChange != null)
        ///             {
        ///                 dirtyFlag = (e.ChangedItemLabel == @"DirtyFlag") ? false : true;
        ///                 docChange(e);
        ///             }
        ///         }
        ///
        ///         public bool IsDirty()
        ///         {
        ///             return dirtyFlag;
        ///         }
        ///
        ///         public string Text
        ///         {
        ///             get { return text; }
        ///             set
        ///             {
        ///                 text = value;
        ///                 DocChangeEvent(new MxDocChangeEventArgs(@"Text", value));
        ///             }
        ///         }
        ///
        ///         public void Save()
        ///         {
        ///             DocChangeEvent(new MxDocChangeEventArgs(@"DirtyFlag", false));
        ///         }
        ///     }
        /// </code>
        /// </example>
        /// <list type="number">
        /// <item><description>add interface IMxDocument and implement its methods - see IsDirty()</description></item>
        /// </list>
        /// <example> 
        /// <code>
        ///     public partial class MainForm : Form , IMainForm
        ///     { 
        ///         public MainForm()
        ///         {
        ///             MxStdApp.Instance.Document.docChange += new MxStdAppDocEventHandler(DocumentChange);
        ///             fileSaveToolStripMenuItem.Enabled = false;
        ///             ....
        ///         }
        ///        public void DocumentChange(MxDocChangeEventArgs e)
        ///         {
        ///             if (e.ChangedItemLabel == @"DirtyFlag")
        ///                 fileSaveToolStripMenuItem.Enabled = false;
        ///             else
        ///                 fileSaveToolStripMenuItem.Enabled = true;
        ///             UpdateFormUI();
        ///         }
        ///         private void textBoxTest_TextChanged(object sender, EventArgs e)
        ///         {
        ///             MxStdApp.Instance.Document.Text = textBoxTest.Text;
        ///         }
        ///         private void fileSaveToolStripMenuItem_Click(object sender, EventArgs e)
        ///         {
        ///             MxStdApp.Instance.Document.Save();
        ///         }
        /// </code>
        /// </example>
        /// </summary>
        /// <summary>
        /// Implement method to determine whether the document has been changed and so needs
        /// saving
        /// </summary> 
        bool IsDirty();
    }

    public class MxDocChangeEventArgs : System.EventArgs
    {
        private readonly string changedItemLabel;
        private readonly object changedValue;

        public MxDocChangeEventArgs(string changedDataItemLabel, object newValue)
        {
            changedItemLabel = changedDataItemLabel;
            changedValue = newValue;
        }
        public string ChangedItemLabel { get { return changedItemLabel; } }
        public object ChangedValue { get { return changedValue; } }
    }
}
